#include "ThreadPool.h"
#include "WorkerThread.h"
#include <cassert>

ThreadPool::ThreadPool() : m_bRun(false) {}

ThreadPool::~ThreadPool() {}

bool ThreadPool::Open(int threadNum)
{
    m_bRun = true;
    for(int i = 0; i < threadNum; ++i)
    {
        WorkerThread *thread = CreateWorkThread();
        if (!thread->Init() || !thread->Activate())
        {
            delete thread;
            continue;
        }
        m_ThreadList.push_back(thread);
    }
    m_bRun = !m_ThreadList.empty();
    return m_bRun;
}

void ThreadPool::Shutdown()
{
    {
        ScopeMutex lock(&m_Mutex);
        m_bRun = false;
    }
    m_Cond.Broadcast();  // 唤醒所有线程

    for(size_t i = 0; i < m_ThreadList.size(); ++i)
    {
        WorkerThread *thread = m_ThreadList[i];
        thread->Join();
        delete thread;
    }
    m_ThreadList.clear();
    while(!m_TaskQueue.empty())
    {
        delete m_TaskQueue.front();
        m_TaskQueue.pop();
    }
}

bool ThreadPool::PostTask(Task *task)
{
    if (!task || !m_bRun) return false;
    {
        ScopeMutex lock(&m_Mutex);
        m_TaskQueue.push(task);
    }
    m_Cond.Signal();
    return true;
}

Task *ThreadPool::GetTask()
{
    ScopeMutex lock(&m_Mutex);
    while(m_TaskQueue.empty())
    {
        if (!m_bRun) return NULL;
        m_Cond.Wait(m_Mutex);
    }
    Task *task = m_TaskQueue.front();
    m_TaskQueue.pop();
    return task;
}

WorkerThread *ThreadPool::CreateWorkThread()
{
    return new WorkerThread(this);
}
